package com.atguigu.gulimall.seckill;

import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;


/**
 * 1.整合sentinel
 *   1)、导入依赖
 *   <dependency>
 *             <groupId>com.alibaba.cloud</groupId>
 *             <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
 *         </dependency>
 *   2）、下载sentinel控制台  sentinel-dashboard-1.6.3.jar
 *   3）、配制sentinel控制台地址信息
 *        spring:
 *          cloud:
 *              sentinel:
 *                  transport:
 *                      port: 8719
 *                      dashboard: localhost:8080
 *   4)、在控制台调整参数  默认所有流控设置保存在内存中，重启失效
 *
 *  2、每一个微服务都导入
 *   <dependency>
 *             <groupId>org.springframework.boot</groupId>
 *             <artifactId>spring-boot-starter-actuator</artifactId>
 *         </dependency>
 *  并配置management.endpoints.web.exposure.include=*
 *
 *  3、自定义sentinel流控返回数据
 *
 *  4、使用sentinel来保护feign远和调用：熔断；
 *     1)、调用方的熔断保护
 *         调用方导入
 *         <dependency>
 *             <groupId>org.springframework.cloud</groupId>
 *             <artifactId>spring-cloud-starter-openfeign</artifactId>
 *         </dependency>
 *         并配置 feign.sentinel.enabled=true
 *         并在调用方远程调用接口public interface SeckillFeignService
 *
 *         @FeignClient(value = "gulimall-seckill",fallback = SeckillFeignServiceFallback.class)
 *         并实现接口  SeckillFeignService
 *
 *         @Component
 *          public class SeckillFeignServiceFallback implements SeckillFeignService {
 *
 *              @Override
 *              public R getskuSeckillInfo(Long skuId) {
 *              log.info("熔断方法调用......getskuSeckillInfo....");
 *              return R.error(BizCodeEnume.TOO_MANY_REQUEST.getCode(),
 *                 BizCodeEnume.TOO_MANY_REQUEST.getMsg());
 *               }
 *          }
 *
 *      2)、调用方手动指定远程服务的降级策略。远程服务被降级处理，会触发我们的熔断回调
 *      3）、服务提供方降级：超大流量的时候，必须牺牲一些远程服务。在服务的提供方（远程服务），指定降级策略；
 *         提供方是在运行的。但不运行自己的业务罗辑，返回的是默认的降级数据(限流数据)
 *
 *         熔断数据在服务调用方，降级数据在服务提供方
 *
 *    1.自定义保护的资源
 *     try(Entry entry = SphU.entry("seckillSkus")){
 *          //业务逻辑
 *     }catch (BlockException e){
 *             log.error("资源被限流{}",e.getMessage());
 *     }
 *
 *     2.基于注解
 *     @SentinelResource(value = "getCurrentSeckillSkusResource",blockHandler = "blockHandlerSeckill")
 *     无论是1，2方式一定要配置被流以后的默认返回
 *
 *     url 请求可以设置统一返回  WebCallbackManager
 *
 */

@EnableRabbit  //用来监听RabbitMQ消息
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class GulimallSeckillApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallSeckillApplication.class, args);
    }

}
